﻿/**
 * \file Partie.cs
 * \brief Classe Partie
 * \author ARTUR Vincent
 * \author LAPERDRIX Pierre
 * \version 1.0
 */
namespace Implem
{
	using Interfaces;
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using System.Text;
    using System.IO;
    using System.Media;
    using System.Windows.Media;
    using System.Security.Cryptography;

    /**
     * \class Partie
     * \brief Objet representant la partie
     */
	public class Partie : IPartie
	{

        /*!< Carte du jeu */
		private Carte _carte;

        /*!< Propriete accedant a l'attribut _carte */
        public Carte Carte
		{
            get { return _carte; }
            set { _carte = value; }
		}

        /*!< Nombre de joueurs de la partie */
		private int _nbJoueurs;

        /*!< Propriete accedant a l'attribut _nbJoueurs */
        public int NbJoueurs
        {
            get { return _nbJoueurs; }
            set { _nbJoueurs = value; }
		}

        /*!< Tableau contenant tous les joueurs */
		private Joueur[] _joueurs;

        /*!< Propriete accedant a l'attribut _joueurs */
        public Joueur[] Joueurs
		{
            get { return _joueurs; }
            set { _joueurs = value; }
		}

        /*!< Joueur courant de la partie */
        public static Joueur joueurCourant;

        /*!< Numero du joueur courant de la partie */
        private int _numJoueurCourant;

        /*!< Propriete accedant a l'attribut _numJoueurCourant */
        public int NumJoueurCourant
        {
            get { return _numJoueurCourant; }
            set { _numJoueurCourant = value; }
        }

        public Partie() 
        {
            Carte = new Carte(new StrategiePetiteCarte());
            NbJoueurs = 1;
            Joueurs = new Joueur[1];
            joueurCourant = Joueurs[0];
            NumJoueurCourant = 0;
        
        }

        /**
         * \fn public Partie(Carte c,int nbJ,Joueur[] j)
         * \brief Constructeur de Partie
         * \param c la carte de la partie
         * \param nbJ le nombre de joueurs
         * \param j le tableau contenant tous les joueurs de la partie
         */
        public Partie(Carte c, int nbJ, Joueur[] j)
        {
            Random rnd = new Random();
            Joueur[] res = j.OrderBy(item => rnd.Next()).Cast<Joueur>().ToArray<Joueur>();
            Carte = c;
            NbJoueurs = nbJ;
            Joueurs = res;
            joueurCourant = res[0];
            NumJoueurCourant = 0;
        }


        /**
         * \fn public void finTour()
         * \brief Methode qui se charge de la fin de tour avec le changement du joueurCourant
         */
        public void finTour()
        {
            Partie.joueurCourant.finTour();
            NumJoueurCourant = (++NumJoueurCourant) % NbJoueurs;
            Partie.joueurCourant = Joueurs[NumJoueurCourant];
        }

        /**
         * \fn public void joueurElimine(Joueur j)
         * \brief Elimine un joueur qui n'a plus d'unités
         * \param j le joueur éliminé
         */
        public void joueurElimine(Joueur j)
        {
            //On recree le tableau de joueurs sans le jouer elimine
            Joueur[] tmp = new Joueur[NbJoueurs - 1];
            int num = 0;
            for (int i = 0; i < NbJoueurs; i++)
            {
                if (Joueurs[i] != j)
                {
                    tmp[num] = Joueurs[i];
                    num++;
                }
            }

            //Changement du tableau de joueurs
            Joueurs = tmp;

            //Diminution du nombre de Joueurs
            NbJoueurs--;
        }

        /**
         * \fn public void save(string filename)
         * \brief Sauvegarde la partie
         * \param filename le chemin du fichier de sauvegarde
         */
        public void save(string filename)
        {
            // Ouverture du flux d'ecriture
            StreamWriter flux = new StreamWriter(filename);

            // Sauvegarde de la carte
            Carte.save(flux);

            // Sauvegarde du numero du joueur courant
            flux.WriteLine(NumJoueurCourant);

            // Sauvegarde du nombre de joueurs
            flux.WriteLine(NbJoueurs);

            // Sauvegarde des joueurs (villes, unites, etc.)
            for (int i = 0; i < NbJoueurs; i++)
            {
                Joueurs[i].save(flux);
            }

            // Fermeture du flux
            flux.Close();
        }


        /**
         * \fn public void load(string filename)
         * \brief Chargement de la partie
         * \param filename le nom du fichier a charger
         */
        public void load(string filename)
        {
            // Vérification de l'existence du fichier
            if (!File.Exists(filename))
            {
                Console.WriteLine("Le fichier spécifié n'existe pas !");
                return;
            }

            // Ouverture du flux de lecture
            StreamReader flux = new StreamReader(filename);

            // Chargement de la carte
            Carte.load(flux);
            
            // Chargement du numero du joueur courant
            NumJoueurCourant = Convert.ToInt32(flux.ReadLine());

            // Chargement du nombre de joueurs
            NbJoueurs = Convert.ToInt32(flux.ReadLine());

           

            Carte.Villes.Clear();
            // Chargement des joueurs (villes, unites, etc.)
            Joueurs = new Joueur[NbJoueurs];
            for (int i = 0; i < NbJoueurs; i++)
            {
                Joueur j = new Joueur("toto", Color.FromRgb(255, 0, 0), typeCivil.eii, new Position(0, 0));
                j.load(flux);
                Joueurs[i] = j;
            }

           
            NumJoueurCourant = (NumJoueurCourant - 1) % NbJoueurs;
            if (NumJoueurCourant < 0) NumJoueurCourant += NbJoueurs;

            //Joueur courant
            joueurCourant = Joueurs[NumJoueurCourant];

            // Fermerture du flux
            flux.Close();
        }


	}
}

